package com.activenetwork.smlite.page.rfp.RfpMaintenanceView;

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.events.EventFiringWebDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.activenetwork.custom.uielement.UIElement;
import com.activenetwork.custom.uielement.decorate.InJson;
import com.activenetwork.listener.ImplicitlyWaitListener;
import com.activenetwork.schema.model.vendor.EPVendorSearchType;
import com.activenetwork.smlite.page.rfp.RfpBasicsSubview;
import com.activenetwork.util.EnvContext;
import com.activenetwork.util.PageLoader;
import com.activenetwork.util.WaitUtil;
import com.activenetwork.util.WebDriverFactory;
import com.google.common.collect.Lists;

public class RfpVendorSearch extends RfpBasicsSubview {
	private Logger logger = LoggerFactory.getLogger(RfpVendorSearch.class);
	
	@InJson
	private UIElement conditionLocation;
	@InJson
	private UIElement conditionVenue;
	@InJson
	private UIElement goBtn;
	/**
	 * 
	 * @param location
	 */
	public void setLocationCondition(String location){
		conditionLocation.clear();
		conditionLocation.sendKeys(location);
	}
	/**
	 * 
	 * @param venue
	 */
	public void setVenueCondition(String venue){
		conditionVenue.clear();
		conditionVenue.sendKeys(venue);
	}
	/**
	 * 
	 * @return
	 */
	public RfpVendorSearch clickGo(){
		goBtn.click();
		return PageLoader.load(RfpVendorSearch.class);
	}
	/**
	 * After click next page of vendor table, it will pop up
	 * loading progress bar
	 * @return
	 */
	public RfpVendorSearch waitForProgressBar(){
		WaitUtil waitUtil = new WaitUtil();
		WebDriver driver = EnvContext.webDriverTL.get();
		WebElement progressBar = driver.findElement(By.cssSelector(".PopupBorderContainer[name='ProgressBar']"));
		// loop wait until the progress bar disappear
		int looptime = 0;
		while(true){
			String style = progressBar.getAttribute("style");
			if(StringUtils.containsIgnoreCase(style, "display: none")){
				break;
			}else{
				waitUtil.wait(500);
				looptime++;
			}
			if(looptime > 5) break; // force break for safety
		}
		return PageLoader.load(RfpVendorSearch.class);
	}
	/**
	 * 
	 * @return
	 */
	public RfpVendorSearch waitForAddVendorAlert(){
		WaitUtil waitUtil = new WaitUtil();
		WebDriver driver = EnvContext.webDriverTL.get();
		try{
			WebElement progressBar = driver.findElement(By.cssSelector(".PopupBorderContainer[name='PopupAlert']"));
			// loop wait until the progress bar disappear
			int looptime = 0;
			while(true){
				String style = progressBar.getAttribute("style");
				if(StringUtils.containsIgnoreCase(style, "display: none")){
					break;
				}else{
					waitUtil.wait(500);
					looptime++;
				}
				if(looptime > 5) break; // force break for safety
			}
		}catch(StaleElementReferenceException e){
			
		}
		
		return PageLoader.load(RfpVendorSearch.class);
	}
	/**
	 * 
	 * @return
	 */
	public WebElement getFirstPageLink(){
		WebDriver driver = EnvContext.webDriverTL.get();
		List<WebElement> bottomNavigationPageNumberLink = driver.findElements(By.cssSelector(".SearchResults.GreyShadowContainer .Pagination.Bottom a[name='PageNumButton']"));
		for(WebElement link : bottomNavigationPageNumberLink){
			WebElement span = link.findElement(By.xpath("./span[2]"));
			if(span.getText().trim().equals("1")){
				return link;
			}
		}
		return null;
	}
	/**
	 * 
	 * @return
	 */
	public WebElement getNextPageLink(){
		WebElement nextPage = null;
		WebDriver driver = EnvContext.webDriverTL.get();
		try{
			WebDriverFactory.unwrap((EventFiringWebDriver)driver, new ImplicitlyWaitListener());
			nextPage = driver.findElement(By.cssSelector(".SearchResults.GreyShadowContainer .Pagination.Bottom a[name='NextPageButton']"));
		}catch(NoSuchElementException e){
			
		}finally{
			WebDriverFactory.wrap((EventFiringWebDriver)driver, new ImplicitlyWaitListener());
		}
		return nextPage;
	}
	/**
	 * 
	 * @return
	 */
	public WebElement getPreviousPageLink(){
		WebElement previousPage = null;
		WebDriver driver = EnvContext.webDriverTL.get();
		try{
			WebDriverFactory.unwrap((EventFiringWebDriver)driver, new ImplicitlyWaitListener());
			previousPage = driver.findElement(By.cssSelector(".SearchResults.GreyShadowContainer .Pagination.Bottom a[name='PrePageButton']"));
		}catch(NoSuchElementException e){
			
		}finally{
			WebDriverFactory.wrap((EventFiringWebDriver)driver, new ImplicitlyWaitListener());
		}
		return previousPage;
	}
	/**
	 * 
	 * @param vendorSearch
	 * @return
	 */
	public RfpVendorSearch bookVendorByDataObject(EPVendorSearchType vendorSearch){		
		return matchVendorOnCurrentPage(vendorSearch.getResult());
	}
	/**
	 * 
	 * @param vendorName
	 * @return
	 */
	public RfpVendorSearch bookVendorByName(String vendorName){
		// construct a result object
		EPVendorSearchType.Result result = new EPVendorSearchType.Result();
		result.setVendorName(vendorName);
		// match vendor on the current page
		return matchVendorOnCurrentPage(result);
	}
	/**
	 * 
	 * @param oid
	 * @return
	 */
	public RfpVendorSearch bookVendorByOID(String oid){
		// construct a result object
		EPVendorSearchType.Result result = new EPVendorSearchType.Result();
		result.setVendorOID(oid);
		// match vendor on the current page
		return matchVendorOnCurrentPage(result);
	}
	/**
	 * 
	 * @param result
	 * @return
	 */
	private RfpVendorSearch matchVendorOnCurrentPage(EPVendorSearchType.Result result){
		RfpVendorSearch instance = PageLoader.load(RfpVendorSearch.class);
		// loop all vendor on the current page to check
		WebDriver driver = EnvContext.webDriverTL.get();
		List<WebElement> recordset = driver.findElements(By.xpath("//div[contains(@id, 'ResultVendor_')]"));
		for(WebElement record : recordset){
			instance = instance.addVendor(record, result);
		}
		return instance;
	}
	/**
	 * 
	 * @param targetVendorRow
	 * @param result
	 * @return
	 */
	private RfpVendorSearch addVendor(WebElement targetVendorRow, EPVendorSearchType.Result result){
		List<ResultCondition> conditions = Lists.newArrayList();
		// This can be extended to use any part of vendor information to match
		if(result.getVendorName() != null){
			By titleBy = By.xpath(".//div[@class='RecordTitle --RecordTitle']//a");
			String targetName = targetVendorRow.findElement(titleBy).getAttribute("title").trim();
			conditions.add(new ResultCondition(result.getVendorName(), targetName));
		}
		if(result.getVendorOID() != null){
			//String targetOID = targetVendorRow.findElement(By.xpath(".//div[@class='Hide VendorOID']")).getText().trim();
			String vendorID = targetVendorRow.getAttribute("id").trim();
			String targetOID = vendorID.substring("ResultVendor_".length());
			conditions.add(new ResultCondition(result.getVendorOID(), targetOID));
		}
		
		boolean match = true;
		for(ResultCondition condition : conditions){
			match = match & condition.match();
			if(!match) break;
		}
		
		if(match){
			WebElement plus = targetVendorRow.findElement(By.xpath(".//div[@class='RecordButtonBar']//a[@name='AddToCartLink']"));
			logger.info("Found " + result.getVendorName() + " add to chart");
			plus.click();
			return waitForAddVendorAlert();
		}else{
			return this;
		}
	}
	/**
	 * 
	 * @return
	 */
	public RfpBasicsSubview clickContinue(){
		WebDriver driver = EnvContext.webDriverTL.get();
		try{
			WebDriverFactory.unwrap((EventFiringWebDriver)driver, new ImplicitlyWaitListener());
			WebElement continueBtn = driver.findElement(By.cssSelector("#RequestPriceButton"));
			continueBtn.click();
		}catch(NoSuchElementException e){
			throw new RuntimeException("Unable to select any vendor for sending rfp");
		}finally{
			WebDriverFactory.wrap((EventFiringWebDriver)driver, new ImplicitlyWaitListener());
		}
		return PageLoader.load(RfpReview.class);
	}
	/**
	 * Check if the vendor is added in the chart
	 * @param vendorName
	 * @return
	 */
	public boolean isVendorAdded(String vendorName){
		WebDriver driver = EnvContext.webDriverTL.get();
		List<WebElement> spans = null;
		try{
			WebDriverFactory.unwrap((EventFiringWebDriver)driver, new ImplicitlyWaitListener());
			spans = driver.findElements(By.cssSelector(".ShoppingCartRecord>a:first-child>span"));
		}finally{
			WebDriverFactory.wrap((EventFiringWebDriver)driver, new ImplicitlyWaitListener());
		}
		
		for(WebElement span : spans){
			System.out.println("Vendor in chart <" + span.getText().trim() + ">" + " compared to target vendor <" + vendorName + ">"); 
			if(span.getText().trim().equals(vendorName)){
				return true;
			}
		}
		return false;

	}
	
}

class ResultCondition{
	private String expect;
	private String actual;
	
	public ResultCondition(String expect, String actual){
		this.expect = expect;
		this.actual = actual;
	}
	
	public boolean match(){
		if(expect.equals(actual)){
			return true;
		}else{
			return false;
		}
	}
}
